//
// Maths.cpp for  in /home/goldbe_y//tek3/Projets/Maths/302graphe
// 
// Made by yoni goldberg
// Login   <goldbe_y@epitech.net>
// 
// Started on  Mon Sep 24 14:39:22 2012 yoni goldberg
// Last update Tue Oct 23 15:15:23 2012 yoni goldberg
//

#include "Maths.hpp"

Maths::Maths(const std::string &str)
{
  Parse	tmp(str);

  _nb_contrainte = tmp.getNbContrainte();
  _nb_task = tmp.getNbTask();
  _contrainte = tmp.get_contrainte();
  _task = tmp.get_task();
  _time = tmp.get_time();

  _p = new std::string[_nb_task];
  for (int i = 0; i < _nb_task; i++)
    _p[i] = "";
  _s = new std::string[_nb_task];
  for (int i = 0; i < _nb_task; i++)
    _s[i] = "";
  find_p();

  _cumul = new float[_nb_task + 1];
  for (int i = 0; i < _nb_task + 1; i++)
    _cumul[i] = 0;
  find_cumul();

  _cumul2 = new float[_nb_task + 1];
  for (int i = 0; i < _nb_task + 1; i++)
    _cumul2[i] = 0;
  find_cumul2();
  find_path('a');
  _path += _task[_nb_task - 1];
}

Maths::~Maths()
{
}

std::string			Maths::get_path()
{
  return _path;
}

float				*Maths::get_cumul()
{
  return _cumul;
}

float				*Maths::get_cumul2()
{
  return _cumul2;
}

std::vector<float>		Maths::get_time()
{
  return _time;
}

std::string			*Maths::get_p()
{
  return _p;
}

std::string			&Maths::get_task()
{
  return _task;
}

std::vector<std::string>	&Maths::get_contrainte()
{
  return _contrainte;
}

int				Maths::getNbTask() const
{
  return _nb_task;
}

int				Maths::getNbContrainte() const
{
  return _nb_contrainte;
}

void				Maths::find_p()
{
  for (int i = 0; i < _nb_contrainte; i++)
    _p[_contrainte[i][2] - 'a'] += _contrainte[i][0];
  for (int i = 0; i < _nb_contrainte; i++)
    _s[_contrainte[i][0] - 'a'] += _contrainte[i][2];
}

void				Maths::find_cumul()
{
  for (int i = 0; i < _nb_contrainte; i++)
    _cumul[_contrainte[i][2] - 'a'] = _cumul[_contrainte[i][0] - 'a'] + _time[_contrainte[i][0] - 'a'] > _cumul[_contrainte[i][2] - 'a'] ? _cumul[_contrainte[i][0] - 'a'] + _time[_contrainte[i][0] - 'a'] : _cumul[_contrainte[i][2] - 'a'];
  _cumul[_nb_task] = _cumul[_nb_task - 1] + _time[_nb_task - 1];  
  
}

void				Maths::find_cumul2()
{
  for (int i = _nb_task - 1; i >= 0; i--)
    if (_s[i].size() == 0)
      {
	_cumul2[i] = _cumul[_nb_task] - _time[i];
      }
    else
      {
	_cumul2[i] = _cumul2[_s[i][0] - 'a'] - _time[i];
	for (int j = 1; j < _s[i].size(); j++)
	  _cumul2[i] = _cumul2[_s[i][j] - 'a'] - _time[i] < _cumul2[i] ? _cumul2[_s[i][j] - 'a'] - _time[i] : _cumul2[i];
      }
}

bool				Maths::is_crit(char c)
{
  if (_cumul[c - 'a'] == _cumul2[c - 'a'])
    return true;
  return false;
}

void				Maths::find_path(char c)
{
  for (int i = 0; i < _s[c - 'a'].size(); i++)
    if (is_crit(_s[c - 'a'][i]))
      {
	_path += c;
	find_path(_s[c - 'a'][i]);
	break;
      }
}
